#include "graphic_polygon.h"
#include <iostream>
#include <fstream>



namespace polygon{
	
	point2d_t GetPolygonCOG(const point2d_t *pt, int num, float_t &area_weight) {
		//ASSERT(num >= 3);

		point2d_t a, b, c;
		a = pt[0];
		float_t weight, triangle_weight;
		point2d_t center, triangle_center;

		weight = 0;
		for (int i = 2; i < num; i++) {
			b = pt[i - 1];
			c = pt[i];
			getTriangleCOG(a, b, c, triangle_center, triangle_weight);
			getLineCOG(triangle_center, triangle_weight, center, weight, center, weight);
		}
		area_weight = weight;
		//std::cout << center[0] << '\t' << center[1] << std::endl;
		return center;
	}

	bool intersect(const point2d_t *pts, int num, const point2d_t &a, const point2d_t &b, 
		int intersect_pos[2], float_t intersect_ratio[2])
	{
		int intersect_num = 0;
		for (int i = 0; i < num; i++) {
			const point2d_t &c = pts[i];
			const point2d_t &d = pts[(i+1)%num];
			point2d_t tmp;
			if (line_intersect(c, d, a, b, tmp)) {
				intersect_pos[intersect_num] = i;
				intersect_ratio[intersect_num] = wykobi::is_equal((tmp[0] - c[0]), float_t(0.0)) ? 
					((tmp[1] - c[1]) / (d[1] - c[1])) : ((tmp[0] - c[0]) / (d[0] - c[0]));
				intersect_num++;
				ASSERT(intersect_num <= 2);
			}
		}
		if (2 == intersect_num) {
			if (FLOAT_IS_NOT_ZERO(intersect_ratio[0]) && FLOAT_IS_NOT_ZERO(intersect_ratio[1]))
				return true;
		}
		return false;
	}

	bool CreateNewPolygonsFromIntersect(const point2d_t *pts, int num, int intersect_pos[2], 
		float_t intersect_ratio[2], pPoint2d &polygon0, int & polygon0_point_num, 
		pPoint2d &polygon1, int & polygon1_point_num)
	{
		ASSERT(intersect_pos[1] > intersect_pos[0] && num > intersect_pos[1]);

		polygon0_point_num = num - (intersect_pos[1] - intersect_pos[0] ) + 2;
		polygon1_point_num = (intersect_pos[1] - intersect_pos[0] ) + 2;

		ASSERT(polygon0_point_num > 0 && polygon1_point_num > 0);

		polygon0 = new point2d_t[polygon0_point_num];
		polygon1 = new point2d_t[polygon1_point_num];

		ASSERT(polygon0 && polygon1);

		polygon0_point_num = 0;
		for (int i = 0; i <= intersect_pos[0]; i++) {
			polygon0[polygon0_point_num++] = pts[i%num];
		}

		polygon0[polygon0_point_num++] = pts[intersect_pos[0]] + 
			(pts[(intersect_pos[0]+1) % num] - pts[intersect_pos[0]]) * intersect_ratio[0];
		
		polygon1_point_num = 0;
		polygon1[polygon1_point_num++] = polygon0[polygon0_point_num-1];

		for (int i = intersect_pos[0] + 1; i <= intersect_pos[1] ; i++) {
			polygon1[polygon1_point_num++] = pts[i%num];
		}

		polygon0[polygon0_point_num++] = pts[intersect_pos[1]] + 
			(pts[(intersect_pos[1]+1) % num] - pts[intersect_pos[1]]) * intersect_ratio[1];
		polygon1[polygon1_point_num++] = polygon0[polygon0_point_num-1];

		for (int i = intersect_pos[1] + 1; i < num; i++) {
			polygon0[polygon0_point_num++] = pts[i%num];
		}
		
		return true;
	}

	void test()
	{
#ifdef WIN32
		_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
		//_CrtSetBreakAlloc(144);
		//_CrtSetBreakAlloc(142);
		//_CrtSetBreakAlloc(288);
		
#endif // WIN32


		point2d_t a, b, c;
		a = 50, 0;
		b =100, 0;
		c = 50, 100;

		point2d_t pt[6];
		pt[0] = 0,0;
		pt[1] = 50,0;
		pt[2] = 100,100;
		pt[3] = 50,100;
		pt[4] = -50,100;
		pt[5] = -50,0;

		point2d_t center;
		float_t weight;
		getTriangleCOG(b, a, c, center, weight);
		std::cout << weight << std::endl;

		center = GetPolygonCOG(pt, 4, weight);
		int intersect_pos[2];
		float_t intersect_ratio[2];
		intersect(pt, 4, point2d_t(100, 0), point2d_t(0, 100), intersect_pos, intersect_ratio);

		pPoint2d polygon0, polygon1;
		int num0, num1;
		CreateNewPolygonsFromIntersect(pt, 4, intersect_pos, intersect_ratio, polygon0, num0, polygon1, num1);
		delete[] polygon0;
		delete[] polygon1;
		std::cout << point_in_polygon(50, 40, pt, 4);
	}

	class Ctest {
	public:
		Ctest() {
			test();

		}
	};

};
//polygon::Ctest g_test;